

#include <stdint.h>
#include <string.h>
#include "i7816_define.h"
#include "i7816_config.h"
#include "i7816_hal.h"
#include "i7816_log.h"
#include "i7816_activate.h"
#include "i7816_t1.h"
#include "i7816_t0.h"

#define CHECK_ID(id)	if((id) >= IFD_NUM){ return I7816_S_INVALID_ID;}

extern i7816_ifd_t i7816_ifd[IFD_NUM];


void i7816_init(void){
	i7816_config_init();
}

i7816_icc_state_t i7816_check_state(uint8_t id){
	if(id >= IFD_NUM){
		return ICC_ST_ABSENT;
	}
	//检测卡是否在卡槽
	i7816_ifd_t* ifd = &i7816_ifd[id];
	if(i7816_hal_check_present(ifd->hw)){
		ifd->state |= ICC_ST_PRESENT;
	}
	else{
		ifd->state &= ~ICC_ST_PRESENT;
	}
	return ifd->state;
}

i7816_status_t i7816_power_on(uint8_t id){
	CHECK_ID(id);
	i7816_ifd_t* ifd = &i7816_ifd[id];
	if(ifd->state & ICC_ST_ACTIVATED){
		i7816_deactivate(ifd);
		i7816_hal_delay_ms(5);
	}
	i7816_status_t status = i7816_activate(ifd);
	if(status != I7816_S_OK){
		ifd->state &= ~ ICC_ST_ACTIVATED;
	}
	else{
		ifd->state |= ICC_ST_ACTIVATED;
	}
	return status;
}

i7816_status_t i7816_power_off(uint8_t id){
	CHECK_ID(id);
	i7816_ifd_t* ifd = &i7816_ifd[id];
	i7816_deactivate(ifd);
	ifd->state &= ~ ICC_ST_ACTIVATED;
	return I7816_S_OK;
}

i7816_status_t i7816_exchange_apdu(uint8_t id, const uint8_t* capdu, uint16_t clen , uint8_t* rapdu, uint16_t* rlen){
	CHECK_ID(id);
	i7816_ifd_t* ifd = &i7816_ifd[id];
//		i7816_hal_select(ifd->hw);
	i7816_hal_config(ifd->hw, &ifd->param);
	if(ifd->param.protocol == PROTOCOL_T1){
		return i7816_t1_exchange(ifd, (uint8_t*)capdu, clen, rapdu, rlen);
	}
	if(ifd->param.protocol == PROTOCOL_T0){
		return i7816_t0_exchange(ifd, (uint8_t*)capdu, clen, rapdu, rlen);
	}
	return I7816_S_NOT_READY;
}

i7816_status_t i7816_get_atr(uint8_t id, uint8_t *atr, uint8_t* alen){
	CHECK_ID(id);
	if(!atr || !alen){
		return I7816_S_INVALID_ARGS;
	}

	i7816_ifd_t* ifd = &i7816_ifd[id];
	if(!(ifd->state & ICC_ST_ACTIVATED)){
		return I7816_S_NOT_READY;
	}

	*alen = ifd->icc.alen;
	memcpy(atr, ifd->icc.atr, *alen);
	return I7816_S_OK;
}

int i7816_is_activated(uint8_t id){
	i7816_ifd_t* ifd = &i7816_ifd[id];
	return ifd->state & ICC_ST_ACTIVATED;
}



